package com.neusoft.thread4notify;

import java.util.ArrayList;
import java.util.List;
/** 
 * Java中的等待/通知机制是实现线程间通信的一种方式，是通过wait/notify/notifyAll等方法来完成的和synchronized联合使用
 * 在每个对象的监视器锁上面都维护着两个队列，一个是同步队列，一个是等待队列。对于等待队列中的线程只有收到特定的通知信号才能迁移到同步队列。
 * 
 * 
 * 例如：定义一个盘子类，可以放鸡蛋和取鸡蛋 
 * */
public class Plate 
{
	/** 
	 * 装鸡蛋的盘子 
	 * */
	List<Object> eggs = new ArrayList<Object>(10);
	/** 
	 * 取鸡蛋 
	 * */
	public synchronized Object getEgg() 
	{
		while (eggs.size() == 0) 
		{
			try 
			{
				wait();
			} 
			catch (InterruptedException e) 
			{
				e.printStackTrace();
			}
		}
		Object egg = eggs.get(0);
		eggs.remove(egg);
		notify();// 唤醒阻塞队列的某线程到就绪队列
		System.out.println("拿走鸡蛋,盘子中有"+eggs.size()+"个鸡蛋");
		return egg;
	}
	/** 
	 * 放鸡蛋 
	 * */
	public synchronized void putEgg(Object egg) 
	{
		while (eggs.size() >0) 
		{
			try 
			{
				wait();
			} 
			catch (InterruptedException e) 
			{
				e.printStackTrace();
			}
		}
		eggs.add(egg);// 往盘子里放鸡蛋
		notify();// 唤醒阻塞队列的某线程到就绪队列
		System.out.println("放入鸡蛋,盘子中有"+eggs.size()+"个鸡蛋");
	}

	public static void main(String args[]) 
	{
		Plate plate = new Plate();
		for(int i = 0; i < 10; i++)
		{
			new Thread(new Customer(plate)).start();
			new Thread(new Producer(plate)).start();
		}
	}
}
/**
 * 消费者：取鸡蛋
 * @author Zhang.Yan
 *
 */
class Customer implements Runnable
{
	private Plate plate;
	
	public Customer(Plate plate) 
	{
		this.plate = plate;
	}
	
	@Override
	public void run() 
	{
		plate.getEgg();
	}
	
}

/**
 * 生成者:生产鸡蛋
 * @author Zhang.Yan
 *
 */
class Producer implements Runnable
{
	private Plate plate;
	private Object egg = new Object();
	
	public Producer(Plate plate) 
	{
		this.plate = plate;
	}
	@Override
	public void run() 
	{
		plate.putEgg(egg);
	}
}

